﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;
using System.Xml;
using System.Xml.Serialization;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Soap;
using System.Threading;
using System.Diagnostics;

namespace PIM_ATE
{
    public static class IniFile
    {
        /// <summary>
        /// 地址
        /// </summary>
        public static string Path { get; private set; }

        #region API函数
        [DllImport("kernel32")]
        private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);

        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section, string key, string defVal, StringBuilder retVal, int size, string filePath);

        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section, string key, string defVal, Byte[] retVal, int size, string filePath);
        #endregion

        /// <summary>
        /// 设置地址
        /// </summary>
        /// <param name="path"></param>
        internal static void SetFileName(string path)
        {
            Path = path;
        }

        /// <summary>
        /// 写
        /// </summary>
        /// <param name="section"></param>
        /// <param name="key"></param>
        /// <param name="iValue"></param>
        public static void IniWriteValue(string section, string key, string iValue)
        {
            WritePrivateProfileString(section, key, iValue, Path);
        }

        /// <summary>
        /// 读
        /// </summary>
        /// <param name="section"></param>
        /// <param name="key"></param>
        /// <param name="defval"></param>
        /// <returns></returns>
        public static string IniReadValue(string section, string key, string defval)
        {
            StringBuilder temp = new StringBuilder(255);
            int i = GetPrivateProfileString(section, key, defval, temp, 255, Path);
            return temp.ToString();
        }
    }

    public class XmlUtil
    {
        public XmlUtil() { }

        #region XML Serialization

        public static string ToXml(Object objToXml, bool includeNameSpace, bool omit)
        {
            XmlWriter stWriter = null;
            XmlSerializer xmlSerializer;
            string buffer;
            try
            {
                xmlSerializer = new XmlSerializer(objToXml.GetType());

                StringBuilder sb = new StringBuilder();
                stWriter = XmlWriter.Create(sb, new XmlWriterSettings() { OmitXmlDeclaration = omit });

                if (!includeNameSpace)
                {
                    System.Xml.Serialization.XmlSerializerNamespaces xs = new XmlSerializerNamespaces();
                    xs.Add("", "");//To remove namespace and any other inline information tag
                    xmlSerializer.Serialize(stWriter, objToXml, xs);
                }
                else
                {
                    xmlSerializer.Serialize(stWriter, objToXml);
                }
                buffer = sb.ToString();
            }
            catch (Exception Ex)
            {
                throw Ex;
            }
            finally
            {
                if (stWriter != null) stWriter.Close();
            }
            return buffer;
        }

        /// <summary>
        /// Converts an object to an xml string.
        /// </summary>
        /// <param name="objToXml">Object wanted to be converted to xml string</param>
        /// <returns>Xml string of the object</returns>		
        public static string ToXml(Object objToXml, bool includeNameSpace)
        {
            StreamWriter stWriter = null;
            XmlSerializer xmlSerializer;
            string buffer;
            try
            {
                xmlSerializer = new XmlSerializer(objToXml.GetType());
                MemoryStream memStream = new MemoryStream();
                stWriter = new StreamWriter(memStream);
                if (!includeNameSpace)
                {
                    System.Xml.Serialization.XmlSerializerNamespaces xs = new XmlSerializerNamespaces();
                    xs.Add("", "");//To remove namespace and any other inline information tag
                    xmlSerializer.Serialize(stWriter, objToXml, xs);
                }
                else
                {
                    xmlSerializer.Serialize(stWriter, objToXml);
                }
                buffer = Encoding.ASCII.GetString(memStream.GetBuffer());
            }
            catch (Exception Ex)
            {
                throw Ex;
            }
            finally
            {
                if (stWriter != null) stWriter.Close();
            }
            return buffer;
        }

        /// <summary>
        /// Serializes a given object to the file given with the path
        /// </summary>
        /// <param name="objToXml">Object wanted to be serialized to the file</param>
        /// <param name="filePath">Path of the file</param>		
        public static void ToXml(Object objToXml, string filePath, bool includeNameSpace)
        {
            StreamWriter stWriter = null;
            XmlSerializer xmlSerializer;
            try
            {
                xmlSerializer = new XmlSerializer(objToXml.GetType());
                stWriter = new StreamWriter(filePath);
                if (!includeNameSpace)
                {
                    System.Xml.Serialization.XmlSerializerNamespaces xs = new XmlSerializerNamespaces();
                    xs.Add("", "");//To remove namespace and any other inline information tag
                    xmlSerializer.Serialize(stWriter, objToXml, xs);
                }
                else
                {
                    xmlSerializer.Serialize(stWriter, objToXml);
                }
            }
            catch (Exception exception)
            {
                throw exception;
            }
            finally
            {
                if (stWriter != null) stWriter.Close();
            }
        }

        /// <summary>
        /// Serializes a given object to the file given with the path
        /// </summary>
        /// <param name="objToXml">Object wanted to be serialized to the file</param>
        /// <param name="includeStartDocument">Includes the <?xml version="1.0" encoding="utf-8" ?> line if it is true, otherwise start doucment line is excluded from the exported xml.</param>
        /// <param name="filePath">Path of the file</param>		
        public static void ToXml(Object objToXml, string filePath, bool includeNameSpace, bool includeStartDocument)
        {
            SpecialXmlWriter stWriter = null;
            XmlSerializer xmlSerializer;
            try
            {
                xmlSerializer = new XmlSerializer(objToXml.GetType());
                stWriter = new SpecialXmlWriter(filePath, null, includeStartDocument);
                System.Xml.Serialization.XmlSerializerNamespaces xs = new XmlSerializerNamespaces();
                xs.Add("", "");//To remove namespace and any other inline information tag
                xmlSerializer.Serialize(stWriter, objToXml, xs);
            }
            catch (Exception Ex)
            {
                throw Ex;
            }
            finally
            {
                if (stWriter != null) stWriter.Close();
            }
        }

        /// <summary>
        /// Deserializes the object given with the type from the given string
        /// </summary>
        /// <param name="xmlString">String containing the serialized xml form of the object</param>
        /// <param name="type">Type of the object to be deserialized</param>
        /// <returns>Deserialized object</returns>
        public static object XmlTo(string xmlString, Type type)
        {
            XmlSerializer xmlSerializer;
            MemoryStream memStream = null;
            try
            {
                xmlSerializer = new XmlSerializer(type);
                byte[] bytes = new byte[xmlString.Length];
                Encoding.ASCII.GetBytes(xmlString, 0, xmlString.Length, bytes, 0);
                memStream = new MemoryStream(bytes);
                object objectFromXml = xmlSerializer.Deserialize(memStream);
                return objectFromXml;
            }
            catch (Exception Ex)
            {
                throw Ex;
            }
            finally
            {
                if (memStream != null) memStream.Close();
            }
        }

        /// <summary>
        /// Deserializes the object given with the type from the given string
        /// </summary>
        /// <param name="xmlString">String containing the serialized xml form of the object</param>
        /// <param name="type">Type of the object to be deserialized</param>
        /// <returns>Deserialized object</returns>
        public static object XmlToFromFile(string filePath, Type type)
        {
            XmlSerializer xmlSerializer;
            FileStream fileStream = null;
            try
            {
                xmlSerializer = new XmlSerializer(type);
                fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
                object objectFromXml = xmlSerializer.Deserialize(fileStream);
                return objectFromXml;
            }
            catch (Exception Ex)
            {
                throw Ex;
            }
            finally
            {
                if (fileStream != null) fileStream.Close();
            }
        }

        public static string FormatXml(string source)
        {
            var sb = new StringBuilder();
            XmlTextWriter writer = null;
            try
            {
                var doc = new XmlDocument();
                doc.LoadXml(source);
                writer = new XmlTextWriter(new StringWriter(sb))
                {
                    Formatting = Formatting.Indented
                };
                doc.WriteTo(writer);
            }
            finally
            {
                if (writer != null) writer.Close();
            }

            return sb.ToString();
        }

        public static string FormatInnerXml(string source)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(source);
            if (doc.DocumentElement != null)
            {
                return doc.DocumentElement.InnerXml;
            }

            return source;
        }

        #endregion XML Serialization

        #region SOAP Serialization

        /// <summary>
        /// DeSerializes a string into a  object 
        /// </summary>
        /// <param name="strFieldObject">String to be deserialized</param>
        /// <returns>Deserialized field object</returns>
        public static object SoapTo(string soapString)
        {
            IFormatter formatter;
            MemoryStream memStream = null;
            Object objectFromSoap = null;
            try
            {
                byte[] bytes = new byte[soapString.Length];
                Encoding.ASCII.GetBytes(soapString, 0, soapString.Length, bytes, 0);
                memStream = new MemoryStream(bytes);
                formatter = new SoapFormatter();
                objectFromSoap = formatter.Deserialize(memStream);
            }
            catch (Exception exception)
            {
                throw exception;
            }
            finally
            {
                if (memStream != null) memStream.Close();
            }
            return objectFromSoap;
        }

        /// <summary>
        /// DeSerializes a string into a  object 
        /// </summary>
        /// <param name="strFieldObject">String to be deserialized</param>
        /// <returns>Deserialized field object</returns>
        public static object SoapToFromFile(string filePath)
        {
            IFormatter formatter;
            FileStream fileStream = null;
            Object objectFromSoap = null;
            try
            {
                fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
                formatter = new SoapFormatter();
                objectFromSoap = formatter.Deserialize(fileStream);
            }
            catch (Exception exception)
            {
                throw exception;
            }
            finally
            {
                if (fileStream != null) fileStream.Close();
            }
            return objectFromSoap;
        }

        /// <summary>
        /// Serializes the field object into a string
        /// </summary>
        /// <param name="objField">Field Object to be serialized</param>
        /// <returns>Serialized field object</returns>
        public static string ToSoap(Object objToSoap)
        {
            IFormatter formatter;
            MemoryStream memStream = null;
            string strObject = "";
            try
            {
                memStream = new MemoryStream();
                formatter = new SoapFormatter();
                formatter.Serialize(memStream, objToSoap);
                strObject = Encoding.ASCII.GetString(memStream.GetBuffer());
                int index = strObject.IndexOf("\0");//Check for the null terminator character
                if (index > 0)
                {
                    strObject = strObject.Substring(0, index);
                }
            }
            catch (Exception exception)
            {
                throw exception;
            }
            finally
            {
                if (memStream != null) memStream.Close();
            }
            return strObject;
        }

        /// <summary>
        /// Serializes the field object into a string
        /// </summary>
        /// <param name="objField">Field Object to be serialized</param>
        /// <returns>Serialized field object</returns>
        public static void ToSoap(Object objToSoap, string filePath)
        {
            IFormatter formatter;
            FileStream fileStream = null;
            try
            {
                fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write);
                formatter = new SoapFormatter();
                formatter.Serialize(fileStream, objToSoap);
            }
            catch (Exception exception)
            {
                throw exception;
            }
            finally
            {
                if (fileStream != null) fileStream.Close();
            }
        }

        /// <summary>
        /// DeSerializes a string into a  object 
        /// </summary>
        /// <param name="strFieldObject">String to be deserialized</param>
        /// <returns>Deserialized field object</returns>
        public static object SoapToFromFile(string filePath, SerializationBinder binder)
        {
            IFormatter formatter;
            FileStream fileStream = null;
            Object objectFromSoap = null;
            try
            {
                fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
                formatter = new SoapFormatter();
                formatter.Binder = binder;
                objectFromSoap = formatter.Deserialize(fileStream);
            }
            catch (Exception exception)
            {
                throw exception;
            }
            finally
            {
                if (fileStream != null) fileStream.Close();
            }
            return objectFromSoap;
        }

        #endregion XML Serialization
    }


    public class MiniDumpUtil
    {
        [DllImport("kernel32.dll")]
        private static extern int GetCurrentThreadId();

        [DllImport("DbgHelp.dll")]
        private static extern bool MiniDumpWriteDump(IntPtr hProcess, int processId, IntPtr fileHandle, MiniDumpType dumpType, ref MiniDumpExceptionInfo excepInfo, IntPtr userInfo, IntPtr extInfo);

        [DllImport("DbgHelp.dll")]
        private static extern bool MiniDumpWriteDump(IntPtr hProcess, int processId, IntPtr fileHandle, MiniDumpType dumpType, IntPtr excepParam, IntPtr userInfo, IntPtr extInfo);

        public static bool TryWriteMiniDump(string dmpFileName, MiniDumpType dmpType)
        {
            using (FileStream stream = new FileStream(dmpFileName, FileMode.OpenOrCreate))
            {
                Process process = Process.GetCurrentProcess();
                MiniDumpExceptionInfo exceptionInfo = new MiniDumpExceptionInfo();
                exceptionInfo.ThreadId = GetCurrentThreadId();
                exceptionInfo.ExceptionPointers = Marshal.GetExceptionPointers();
                exceptionInfo.ClientPointers = true;
                if (exceptionInfo.ExceptionPointers == IntPtr.Zero)
                {
                    return MiniDumpWriteDump(process.Handle, process.Id, stream.SafeFileHandle.DangerousGetHandle(), dmpType, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
                }
                else
                {
                    return MiniDumpWriteDump(process.Handle, process.Id, stream.SafeFileHandle.DangerousGetHandle(), dmpType, ref exceptionInfo, IntPtr.Zero, IntPtr.Zero);
                }
            }
        }
    }

    [Flags]
    public enum MiniDumpType
    {
        MiniDumpNormal = 0x00000000,
        MiniDumpWithDataSegs = 0x00000001,
        MiniDumpWithFullMemory = 0x00000002,
        MiniDumpWithHandleData = 0x00000004,
        MiniDumpFilterMemory = 0x00000008,
        MiniDumpScanMemory = 0x00000010,
        MiniDumpWithUnloadedModules = 0x00000020,
        MiniDumpWithIndirectlyReferencedMemory = 0x00000040,
        MiniDumpFilterModulePaths = 0x00000080,
        MiniDumpWithProcessThreadData = 0x00000100,
        MiniDumpWithPrivateReadWriteMemory = 0x00000200,
        MiniDumpWithoutOptionalData = 0x00000400,
        MiniDumpWithFullMemoryInfo = 0x00000800,
        MiniDumpWithThreadInfo = 0x00001000,
        MiniDumpWithCodeSegs = 0x00002000,
        MiniDumpWithoutAuxiliaryState = 0x00004000,
        MiniDumpWithFullAuxiliaryState = 0x00008000,
        MiniDumpWithPrivateWriteCopyMemory = 0x00010000,
        MiniDumpIgnoreInaccessibleMemory = 0x00020000,
        MiniDumpWithTokenInformation = 0x00040000,
        MiniDumpWithModuleHeaders = 0x00080000,
        MiniDumpFilterTriage = 0x00100000,
        MiniDumpValidTypeFlags = 0x001fffff
    }

    public struct MiniDumpExceptionInfo
    {
        public int ThreadId;
        public IntPtr ExceptionPointers;
        public bool ClientPointers;
    }

    #region SpecialXmlWriter

    public class SpecialXmlWriter : XmlTextWriter
    {
        bool m_includeStartDocument = true;
        public SpecialXmlWriter(TextWriter tw, bool includeStartDocument)
            : base(tw)
        {
            m_includeStartDocument = includeStartDocument;
        }
        public SpecialXmlWriter(Stream sw, Encoding encoding, bool includeStartDocument)
            : base(sw, null)
        {
            m_includeStartDocument = includeStartDocument;
        }
        public SpecialXmlWriter(string filePath, Encoding encoding, bool includeStartDocument)
            : base(filePath, null)
        {
            m_includeStartDocument = includeStartDocument;
        }
        public override void WriteStartDocument()
        {
            if (m_includeStartDocument)
            {
                base.WriteStartDocument();
            }
        }
    }

    #endregion SpecialXmlWriter
}
